package cn.edu.sjtu.message_management.service;

import cn.edu.sjtu.message_management.dto.MessageDTO;
import cn.edu.sjtu.message_management.model.Message;
import cn.edu.sjtu.message_management.model.User;
import cn.edu.sjtu.message_management.repository.MessageRepository;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MessageService {
    @Autowired
    private MessageRepository messageRepository;
    @Autowired
    private Mapper mapper;
    @Resource
    private MongoTemplate mongoTemplate;

    public List<Message> getMessage(String userId) {
        return messageRepository.findByToUser_UserIdAndReadIsFalse(userId);
    }

    public boolean read(String Id) {
        Message message = messageRepository.findByMessageId(Id);
        message.setRead(true);
        mongoTemplate.save(message);
        if (messageRepository.save(message) == null) {
            return false;
        }
        return true;
    }

    public List<MessageDTO> getSentMessage(String userId) {
        List<Message> byFrom = messageRepository.findByFromUser_UserId(userId);
        return byFrom.stream().map(message -> mapper.map(message, MessageDTO.class)).collect(Collectors.toList());
    }

    public List<MessageDTO> getUnReadMessage(String userId) {
        List<Message> readIsFalse = messageRepository.findByToUser_UserIdAndReadIsFalse(userId);
        return readIsFalse.stream().map(message -> mapper.map(message, MessageDTO.class)).collect(Collectors.toList());
    }

    public List<MessageDTO> getReadMessage(String userId) {
        List<Message> readIsTrue = messageRepository.findByToUser_UserIdAndReadIsTrue(userId);
        return readIsTrue.stream().map(message -> mapper.map(message, MessageDTO.class)).collect(Collectors.toList());
    }

    public boolean readAll(String userId) {
        List<Message> readIsFalse = messageRepository.findByToUser_UserIdAndReadIsFalse(userId);
        List<Message> collect = readIsFalse.stream().peek(message -> message.setRead(true)).collect(Collectors.toList());
        List<Message> messages = messageRepository.saveAll(collect);
        if (messages == null || messages.size() != collect.size()) {
            return false;
        }
        return true;
    }

    public void save(Message message) {
        List<User> userList = message.getToUser();
        for (User user : userList) {
            Message messageX = Message.builder()
                    .content(message.getContent())
                    .device(message.getDevice())
                    .fromUser(message.getFromUser())
                    .process(message.getProcess())
                    .toUser(Collections.singletonList(user))
                    .time(new Date(System.currentTimeMillis()))
                    .messageId(UUID.randomUUID().toString())
                    .read(false)
                    .type(message.getType()).build();
            messageRepository.save(messageX);
        }
    }
}
